home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / ASTExpressionList.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  7.3 KB  |  247 lines  |  [TEXT/KAHL]

  1. /* ASTExpressionList.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "ASTExpressionList.h"
  31. #include "TrashTracker.h"
  32. #include "Memory.h"
  33. #include "ASTExpression.h"
  34.  
  35.  
  36. struct ASTExprListRec
  37.     {
  38.         struct ASTExpressionRec*        First;
  39.         ASTExprListRec*                            Rest;
  40.     };
  41.  
  42.  
  43. /* cons an AST expression onto a list */
  44. ASTExprListRec*            ASTExprListCons(ASTExpressionRec* First, ASTExprListRec* Rest,
  45.                                             struct TrashTrackRec* TrashTracker)
  46.     {
  47.         ASTExprListRec*        NewNode;
  48.  
  49.         if (First != NIL)
  50.             {
  51.                 CheckPtrExistence(First);
  52.             }
  53.         if (Rest != NIL)
  54.             {
  55.                 CheckPtrExistence(Rest);
  56.             }
  57.  
  58.         NewNode = (ASTExprListRec*)AllocTrackedBlock(sizeof(ASTExprListRec),TrashTracker);
  59.         if (NewNode == NIL)
  60.             {
  61.                 return NIL;
  62.             }
  63.         SetTag(NewNode,"ASTExprListRec");
  64.  
  65.         NewNode->First = First;
  66.         NewNode->Rest = Rest;
  67.  
  68.         return NewNode;
  69.     }
  70.  
  71.  
  72. /* type check a list of expressions.  this returns eCompileNoError if */
  73. /* everything is ok, and the appropriate type in *ResultingDataType. */
  74. CompileErrors                TypeCheckExprList(DataTypes* ResultingDataType,
  75.                                             ASTExprListRec* ExpressionList, long* ErrorLineNumber,
  76.                                             struct TrashTrackRec* TrashTracker)
  77.     {
  78.         CompileErrors            Error;
  79.  
  80.         /* ExpressionList should NOT be NIL, since that's handled by the expression */
  81.         /* container */
  82.         CheckPtrExistence(ExpressionList);
  83.         CheckPtrExistence(TrashTracker);
  84.  
  85.         /* the result type is filled in now */
  86.         Error = TypeCheckExpression(ResultingDataType,ExpressionList->First,
  87.             ErrorLineNumber,TrashTracker);
  88.         if (Error != eCompileNoError)
  89.             {
  90.                 return Error;
  91.             }
  92.  
  93.         /* if there is another one, then do it */
  94.         if (ExpressionList->Rest != NIL)
  95.             {
  96.                 return TypeCheckExprList(ResultingDataType,ExpressionList->Rest,ErrorLineNumber,
  97.                     TrashTracker);
  98.             }
  99.          else
  100.             {
  101.                 return eCompileNoError;
  102.             }
  103.     }
  104.  
  105.  
  106. /* get the first expression */
  107. struct ASTExpressionRec*    ExprListGetFirstExpr(ASTExprListRec* ExpressionList)
  108.     {
  109.         CheckPtrExistence(ExpressionList);
  110.         return ExpressionList->First;
  111.     }
  112.  
  113.  
  114. /* get the tail expression list */
  115. ASTExprListRec*            ExprListGetRestList(ASTExprListRec* ExpressionList)
  116.     {
  117.         CheckPtrExistence(ExpressionList);
  118.         return ExpressionList->Rest;
  119.     }
  120.  
  121.  
  122. /* install a new first in the list */
  123. void                                ExprListPutNewFirst(ASTExprListRec* ExpressionList,
  124.                                             struct ASTExpressionRec* NewFirst)
  125.     {
  126.         CheckPtrExistence(ExpressionList);
  127.         CheckPtrExistence(NewFirst);
  128.         ExpressionList->First = NewFirst;
  129.     }
  130.  
  131.  
  132. /* this is a helper function for generating code */
  133. static MyBoolean        CodeGenSequenceHelper(struct PcodeRec* FuncCode,
  134.                                             long* StackDepthParam, ASTExprListRec* ExpressionList)
  135.     {
  136.         long                            StackDepth;
  137.  
  138.         CheckPtrExistence(FuncCode);
  139.         CheckPtrExistence(ExpressionList);
  140.         StackDepth = *StackDepthParam;
  141.  
  142.         /* generate code for the first expression */
  143.         if (!CodeGenExpression(FuncCode,&StackDepth,ExpressionList->First))
  144.             {
  145.                 return False;
  146.             }
  147.  
  148.         if (ExpressionList->Rest != NIL)
  149.             {
  150.                 /* if there is another expression, then pop the value we just */
  151.                 /* calcuated & evaluate the next one */
  152.                 if (!AddPcodeInstruction(FuncCode,epStackPop,NIL))
  153.                     {
  154.                         return False;
  155.                     }
  156.                 StackDepth -= 1;
  157.                 if (!CodeGenSequenceHelper(FuncCode,&StackDepth,ExpressionList->Rest))
  158.                     {
  159.                         return False;
  160.                     }
  161.             }
  162.         /* else no next one, so just keep it */
  163.  
  164.         *StackDepthParam = StackDepth;
  165.         return True;
  166.     }
  167.  
  168.  
  169. /* generate code for an expression list that is a series of sequential expressions. */
  170. /* returns True if successful, or False if it fails. */
  171. MyBoolean                        CodeGenExpressionListSequence(struct PcodeRec* FuncCode,
  172.                                             long* StackDepthParam, ASTExprListRec* ExpressionList)
  173.     {
  174.         long                            StackDepth;
  175.  
  176.         CheckPtrExistence(FuncCode);
  177.         CheckPtrExistence(ExpressionList);
  178.         StackDepth = *StackDepthParam;
  179.  
  180.         /* generate code for all of the expressions */
  181.         if (!CodeGenSequenceHelper(FuncCode,&StackDepth,ExpressionList))
  182.             {
  183.                 return False;
  184.             }
  185.  
  186.         /* if there are any more than 1 additional value on the stack, then we */
  187.         /* must pop all the other values off, since they are local variables */
  188.         if (StackDepth - *StackDepthParam > 1)
  189.             {
  190.                 if (!AddPcodeInstruction(FuncCode,epStackDeallocateUnder,NIL))
  191.                     {
  192.                         return False;
  193.                     }
  194.                 if (!AddPcodeOperandInteger(FuncCode,StackDepth - *StackDepthParam - 1))
  195.                     {
  196.                         return False;
  197.                     }
  198.                 StackDepth = *StackDepthParam + 1;
  199.             }
  200.         ERROR(StackDepth != *StackDepthParam + 1,PRERR(ForceAbort,
  201.             "CodeGenExpressionListSequence:  stack messed up after recurrance call"));
  202.  
  203.         *StackDepthParam = StackDepth;
  204.         return True;
  205.     }
  206.  
  207.  
  208. /* generate code for an argument list -- all args stay on the stack. */
  209. /* returns True if successful, or False if it fails. */
  210. MyBoolean                        CodeGenExpressionListArguments(struct PcodeRec* FuncCode,
  211.                                             long* StackDepthParam, ASTExprListRec* ExpressionList)
  212.     {
  213.         long                            StackDepth;
  214.  
  215.         CheckPtrExistence(FuncCode);
  216.  
  217.         /* see if there is even any code to be generated */
  218.         if (ExpressionList == NIL)
  219.             {
  220.                 /* nope */
  221.                 return True;
  222.             }
  223.  
  224.         CheckPtrExistence(ExpressionList);
  225.         StackDepth = *StackDepthParam;
  226.  
  227.         /* generate code for the first expression */
  228.         if (!CodeGenExpression(FuncCode,&StackDepth,ExpressionList->First))
  229.             {
  230.                 return False;
  231.             }
  232.         ERROR(StackDepth != *StackDepthParam + 1,PRERR(ForceAbort,
  233.             "CodeGenExpressionListArguments:  stack messed up"));
  234.  
  235.         /* if there's another argument, then do it too */
  236.         if (ExpressionList->Rest != NIL)
  237.             {
  238.                 if (!CodeGenExpressionListArguments(FuncCode,&StackDepth,ExpressionList->Rest))
  239.                     {
  240.                         return False;
  241.                     }
  242.             }
  243.  
  244.         *StackDepthParam = StackDepth;
  245.         return True;
  246.     }
  247.